﻿using System;
using System.Collections.Generic;
using TA.JSON;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.HtmlControls;

namespace TA.Turbo.Controls
{
	/// <summary>
	/// Extends a <see cref="TextBox"/> by displaying an auto-complete list when the user types in it.
	/// </summary>
	[ParseChildren(true)]
	[PersistChildren(false)]
	public class AutoCompleteExtender : BaseComplexControl
	{
		#region PUBLIC
		/// <summary>
		/// Ctor.
		/// </summary>
		public AutoCompleteExtender()
		{
			//_getSuggestions = new ServerEvent<SuggestionsEventArgs>(this, "GetSuggestions");

			Tag = System.Web.UI.HtmlTextWriterTag.Span;
			MinimumPrefixLength = 2;
			CompletionTimeout = 500;
			ListCssClass = "suggestion_list";
		}
		#region PROPS
		#region DEF
		/// <summary>
		/// Props.
		/// </summary>
		protected static new Properties _clientProperties = Define(BaseComplexControl._clientProperties,
			new BasePropertyDefinition[] {
				new ControlIdPropertyDefinition("TargetControlId", "TC", null),
				new PropertyDefinition<string>("ListCssClass", "LC", null),
				new PropertyDefinition<int>("MinimumPrefixLength", "MP", 2),
				new PropertyDefinition<int>("CompletionTimeout", "CT", 300),
			});
		/// <summary>
		/// Props.
		/// </summary>
		public override Properties ClientProperties
		{
			get
			{
				return _clientProperties;
			}
		}
		#endregion
		/// <summary>
		/// The ID of the <see cref="TextBox"/> control to be extended.
		/// </summary>
		public string TargetControlId
		{
			get
			{
				return GetProperty<string>("TargetControlId");
			}
			set
			{
				ViewState["TargetControlId"] = value;
			}
		}
		/// <summary>
		/// Gets the <see cref="TextBox"/> control to be extended.
		/// </summary>
		public Control TargetControl
		{
			get
			{
				return this.FindControlGlobal(TargetControlId);
			}
		}
		/// <summary>
		/// The CSS class to be applied to the auto-complete list.
		/// </summary>
		public string ListCssClass
		{
			get
			{
				return GetProperty<string>("ListCssClass");
			}
			set
			{
				ViewState["ListCssClass"] = value;
			}
		}
		/// <summary>
		/// Minimum number of characters required to fetch the auto-complete list.
		/// </summary>
		public int MinimumPrefixLength
		{
			get
			{
				return GetProperty<int>("MinimumPrefixLength");
			}
			set
			{
				ViewState["MinimumPrefixLength"] = value;
			}
		}
		/// <summary>
		/// The time, in milliseconds, to wait before displaying the auto-complete list.
		/// </summary>
		public int CompletionTimeout
		{
			get
			{
				return GetProperty<int>("CompletionTimeout");
			}
			set
			{
				ViewState["CompletionTimeout"] = value;
			}
		}
		#endregion
		#region EVENTS
		/// <summary>
		/// Raised when the timeout elapses after user stopped typing in the text box.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public ServerEvent<SuggestionsEventArgs> GetSuggestions { get { return this.GetServerEvent<SuggestionsEventArgs>("GetSuggestions"); } }
		#endregion
		#endregion
		#region INTERNAL
		#region VARS
		#endregion
		#region METHODS
		#region INIT
		/// <summary>
		/// Init.
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			HtmlGenericControl ul = new HtmlGenericControl("ul");
			ul.Style[HtmlTextWriterStyle.Display] = "none";
			Controls.Add(ul);

			if (TargetControl is TControl)
				(TargetControl as TControl).Attributes["autocomplete"] = "off";
		}
		/// <summary>
		/// Registers AutoCompleteExtender.js.
		/// </summary>
		protected internal override void RegisterIncludes(IncludeCollection includes)
		{
			base.RegisterIncludes(includes);

			includes.Add(Script.Element_AddClass);
			includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.AutoCompleteExtender.js", typeof(AutoCompleteExtender)));
		}
		#endregion
		#region RENDER
		/// <summary>
		/// Adds position style.
		/// </summary>
		/// <param name="writer"></param>
		protected override void AddAttributesToRender(HtmlTextWriter writer)
		{
			writer.AddStyleAttribute(HtmlTextWriterStyle.Position, "relative");

			base.AddAttributesToRender(writer);
		}
		#endregion
		#region EVENTS
		/// <summary>
		/// Raises events.
		/// </summary>
		/// <param name="name"></param>
		/// <param name="argument"></param>
		public override void RaiseEvent(string name, string argument)
		{
			switch (name)
			{
				case "GetSuggestions":
					SuggestionsEventArgs e = new SuggestionsEventArgs(argument);
					OnGetSuggestions(e);
					this.TPage.ResultCustom = new SuggestionResult { Suggestions = e.Suggestions };
					return;
			}
			base.RaiseEvent(name, argument);
		}
		/// <summary>
		/// Raises the <see cref="GetSuggestions"/> event.
		/// </summary>
		/// <param name="e"></param>
		protected virtual void OnGetSuggestions(SuggestionsEventArgs e)
		{
			GetSuggestions.Raise(this, e);
		}
		#endregion
		#endregion
		#endregion
	}
}
